home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / SCSI Samples 1.0 / SCSI Simple Sample 06⁄15 ƒ / Src / SCSISimpleSample.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-16  |  13.8 KB  |  489 lines  |  [TEXT/KAHL]

  1. /*                                SCSISimpleSample.h                                */
  2. /*
  3.  * SCSISimpleSample.h
  4.  * Copyright © 1992-94 Apple Computer Inc. All Rights Reserved.
  5.  */
  6. #ifdef REZ
  7. #define kApplicationCreator    '????'            /* Rez can't deal with long hex        */
  8. #else
  9. #define kApplicationCreator    0x3F3F3F3FL        /* '????' without trigraphs            */
  10. #endif
  11.  
  12. #define MBAR_MenuBar        1000
  13. #define MENU_Apple            1
  14. #define MENU_File            128
  15. #define MENU_Edit            129
  16. #define MENU_Test            130
  17. #define MENU_CurrentBus        131
  18. #define MENU_CurrentTarget    132
  19. #define MENU_CurrentLUN        133
  20. #define STRS_SenseBase        1000
  21. #define DLOG_About            128
  22.  
  23. #define kMinWindowWidth        200
  24. #define kMinWindowHeight    300
  25. #define kLogLines            512
  26.  
  27. #ifndef REZ
  28. /*
  29.  * These definitions are only for the code files.
  30.  */
  31. #ifndef THINK_C                /* MPW includes            */
  32. #include <Errors.h>
  33. #include <Script.h>
  34. #include <Types.h>
  35. #include <Resources.h>
  36. #include <QuickDraw.h>
  37. #include <Fonts.h>
  38. #include <Events.h>
  39. #include <Windows.h>
  40. #include <ToolUtils.h>
  41. #include <Memory.h>
  42. #include <Menus.h>
  43. #include <Lists.h>
  44. #include <Printing.h>
  45. #include <Dialogs.h>
  46. #include <Packages.h>
  47. #endif
  48.  
  49. #ifndef TRUE
  50. #define TRUE    1
  51. #define FALSE    0
  52. #endif
  53. #ifndef EXTERN
  54. #define EXTERN    extern
  55. #endif
  56.  
  57. #include "MacSCSICommand.h"
  58. #include "LogManager.h"
  59.  
  60. #define kScrollBarWidth        16
  61. #define kScrollBarOffset    (kScrollBarWidth - 1)
  62.  
  63. /*
  64.  * Items in the Apple Menu
  65.  */
  66. enum {
  67.     kAppleAbout = 1
  68. };
  69.  
  70. /*
  71.  * Items in the File Menu
  72.  */
  73. enum {
  74.     kFileCreateLogFile = 1,
  75.     kFileCloseLogFile,
  76.     kFileUnused1,
  77.     kFilePageSetup,
  78.     kFilePrint,
  79.     kFileUnused2,
  80.     kFileDebug,
  81.     kFileUnused3,
  82.     kFileQuit
  83. };
  84.  
  85. enum EditMenu {
  86.     kEditUndo                = 1,
  87.     kEditUnused,
  88.     kEditCut,
  89.     kEditCopy,
  90.     kEditPaste,
  91.     kEditClear
  92. };
  93.  
  94. /*
  95.  * Items in the test Menu
  96.  */
  97. enum {
  98.     kTestEnableNewManager = 1,
  99.     kTestEnableAllLogicalUnits,
  100.     kTestEnableSelectWithATN,
  101.     kTestUnused1,
  102.     kTestDoDisconnect,
  103.     kTestDontDisconnect,
  104.     kTestUnused2,
  105.     kTestListSCSIDevices,
  106.     kTestGetDriveInfo,
  107.     kTestUnitReady,
  108.     kTestReadBlockZero,
  109.     kTestUnused3,
  110.     kTestVerboseDisplay,
  111.     kTestDummyLastEntryThankYouANSICCommittee
  112. };
  113.  
  114. /*
  115.  * This is a parameter block for DoSCSICommandWithSense that contains all of the
  116.  * data needed to perform a SCSI command on either the original or asynchronous
  117.  * SCSI Managers. Note: some of this is used only by one or the other manager.
  118.  */
  119. struct ScsiCmdBlock {
  120.     DeviceIdent            scsiDevice;                /* -> Bus/target/LUN            */
  121.     Ptr                    bufferPtr;                /* -> data buffer                */
  122.     unsigned long        transferSize;            /* -> bytes to transfer            */
  123.     unsigned long        transferQuantum;        /* -> polled or blocksize        */
  124.     unsigned short        statusByte;                /* <- From Status Phase            */
  125.     unsigned long        actualTransferCount;    /* <- Transfer count            */
  126.     Boolean                writeToDevice;            /* -> Need data out?            */
  127.     unsigned long        scsiFlags;                /* -> asynch flags                */
  128.     OSErr                status;                    /* <- Current OSErr                */
  129.     OSErr                requestSenseStatus;        /* <- From RequestSense            */
  130.     SCSI_Command        command;                /* -> Current command            */
  131.     SCSI_Sense_Data        sense;                    /* <- Gets Sense data            */
  132. };
  133. typedef struct ScsiCmdBlock ScsiCmdBlock, *ScsiCmdBlockPtr;
  134. /*
  135.  * Notes on the above:
  136.  *    scsiDevice            Used for both managers, but the original manager
  137.  *                        ignores the bus and LUN designations. The caller
  138.  *                        must stuff the LUN into the command data block.
  139.  *    bufferPtr            If NULL, no read/write is performed.
  140.  *    transferSize        If zero, no read/write is performed.
  141.  *    transferQuantum        This is used by the handshake and TIB setup. Note:
  142.  *                        we support only the simplest "512, 0" handshake
  143.  *                        and TIB. The following values are useful:
  144.  *                            0        transferQuantum := transferSize
  145.  *                            1        force polled read/write
  146.  *                            > 1        blocked read (for example, 512)
  147.  *    statusByte            Returned from the device
  148.  *    actualTransfercount Returned in bytes (transferQuantum sets granularity)
  149.  *    scsiFlags            Set special flags (scsiDontDisconnect) here.
  150.  *    status                Overall operation status (note special status values)
  151.  *    requestSenseStatus    Has status of Request Sense (only if status was
  152.  *                        statusErr, indicating that "Check condition" status.
  153.  */
  154.     
  155. /*
  156.  * These are the things the user can choose from the menu:
  157.  *    ListSCSIDevices                Scan all busses and display info for all
  158.  *                                devices (all targets, all LUNs)
  159.  *    DeviceInquiry                Execute an Inquiry command for this device
  160.  *                                and display the results.
  161.  *    TestUnitReady                Execute a Test Unit Ready command for this
  162.  *                                device and display the results.
  163.  */
  164. void                        DoListSCSIDevices(void);
  165. void                        DoGetDriveInfo(
  166.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  167.         Boolean                    noIntroMsg,
  168.         Boolean                    useAsynchManager
  169.     );
  170. void                        DoTestUnitReady(
  171.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  172.     );
  173. void                        DoReadBlockZero(
  174.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  175.     );
  176. /*
  177.  * These are low-level commands that are needed to scan the bus.
  178.  */
  179. Boolean                        SCSICheckForDevicePresent(
  180.         DeviceIdent                scsiDevice,
  181.         Boolean                    enableAsynchSCSI
  182.     );
  183. /*
  184.  * Check whether the asynchronous SCSI Manager may be called for this bus.
  185.  * This will return a status error if the bus is inaccessable. If successful,
  186.  * it will set useAsynchManager FALSE only if this bus is managed by a
  187.  * third-party SCSI hardware interface that operates by patching the
  188.  * original SCSI Manager traps, or uses some other private interface.
  189.  */
  190. OSErr
  191. SCSIBusAPI(
  192.         DeviceIdent                scsiDevice,
  193.         Boolean                    *useAsynchManager
  194.     );
  195. /*
  196.  * Get the maximum target for a specified bus.
  197.  */
  198. OSErr
  199. SCSIGetMaxTargetID(
  200.         DeviceIdent                        scsiDevice,
  201.         unsigned short                    *maxTarget
  202.     );
  203. /*
  204.  * Return the number of SCSI busses on this system.
  205.  */
  206. OSErr                        SCSIGetHighHostBusAdaptor(
  207.         unsigned short            *lastHostBus
  208.     );
  209. /*
  210.  * Return the SCSI bus ID of the initiator (Macintosh) on this bus. This will
  211.  * normally return 7. It always returns 7 if the asynchronous SCSI Manager is
  212.  * not present on this machine. Errors are serious.
  213.  */ 
  214. OSErr                        SCSIGetInitiatorID(
  215.         DeviceIdent                scsiDevice,
  216.         unsigned short            *initiatorID
  217.     );
  218. /*
  219.  * TRUE if the asynchronous SCSI Manager is running on this machine.
  220.  */
  221. Boolean                        AsyncSCSIPresent(void);
  222.  
  223. /*
  224.  * All commands are performed by this function. If the asynchronous SCSI Manager
  225.  * is present, it is called directly. If it is not present, the original SCSI
  226.  * Manager is called and, if the device returns Check Condition, a Request
  227.  * Sense command is issued.
  228.  */
  229. void                        DoSCSICommandWithSense(
  230.         register ScsiCmdBlockPtr    scsiCmdBlockPtr,
  231.         Boolean                    displayError,
  232.         Boolean                    enableAsynchSCSI
  233.     );
  234.  
  235. /*
  236.  * The following functions display operation results.
  237.  */
  238. void                        ShowSCSIBusID(
  239.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  240.         ConstStr255Param        commandText
  241.     );
  242. void                        ShowRequestSense(
  243.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  244.     );
  245. /*
  246.  * This does the actual formatting and display of the Request Sense results
  247.  */
  248. void                        DoShowRequestSense(
  249.         DeviceIdent                scsiDevice,
  250.         OSErr                    operationStatus,
  251.         OSErr                    requestSenseStatus,
  252.         const SCSI_CommandPtr    scsiCommand,
  253.         const SCSI_Sense_Data    *sensePtr
  254.     );
  255. void                        ShowStatusError(
  256.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  257.         OSErr                    errorStatus,
  258.         const SCSI_CommandPtr    scsiCommand
  259.     );
  260. void                        DoShowSCSICommand(
  261.         const SCSI_CommandPtr    cmdBlock,            /* -> SCSI command            */
  262.         ConstStr255Param        message
  263.     );
  264. /*
  265.  * The inquiry data is stored in SCB.bufferPtr
  266.  */
  267. void                        ShowInquiry(
  268.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  269.     );
  270. void                        DoShowInquiry(
  271.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  272.         const SCSI_Inquiry_Data    *inquiry
  273.     );
  274. void                        ShowDeviceState(
  275.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  276.     );
  277. void                        AppendDeviceID(
  278.         StringPtr                result,
  279.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  280.     );
  281. void                        DisplaySCSIErrorMessage(
  282.         OSErr                    errorStatus,
  283.         ConstStr255Param        errorText
  284.     );
  285. /*
  286.  * Use the SCSI-II command class to determine the command length. Returns
  287.  * zero if the length could not be determined.
  288.  */
  289. unsigned short                SCSIGetCommandLength(
  290.         const Ptr                cmdBlock
  291.     );
  292. /*
  293.  * These two functions are called by DoSCSICommandWithSense to perform the
  294.  * actual operation. OriginalSCSI uses the Inside Mac IV SCSI Manager, while
  295.  * AsyncSCSI uses SCSI Manager 4.3.
  296.  * Return codes:
  297.  *
  298.  *    noErr            normal
  299.  *    unimpErr        AsyncSCSI called, but SCSI Manager 4.3 not installed.
  300.  *    scCommErr        Could not select this device or bus busy (Original only)
  301.  *    statusErr        Device returned "Check condition"
  302.  *    controlErr        Device returned "Busy" (Note: device error)
  303.  *    ioErr            Other (serious) device status -- bug.
  304.  *    sc...            Other (Inside Mac IV) SCSI Manager error
  305.  *    scsi...            Other (SCSI Manager 4.3) error.
  306.  */
  307. OSErr                        OriginalSCSI(
  308.         unsigned short            targetID,            /* Device ID on this bus    */
  309.         const SCSI_CommandPtr    scsiCommand,        /* The actual scsi command    */
  310.         unsigned short            cmdBlockLength,        /* -> Length of CDB            */
  311.         Boolean                    writeToDevice,        /* TRUE to write            */
  312.         Ptr                        bufferPtr,            /* -> user data buffer        */
  313.         unsigned long            transferSize,        /* How much to transfer        */
  314.         unsigned long            transferQuantum,    /* TIB setup parameter        */
  315.         unsigned long            completionTimeout,    /* Ticks to wait            */
  316.         unsigned short            *stsBytePtr,        /* <- status phase byte        */
  317.         unsigned long            *actualTransferCount
  318.     );
  319. /*
  320.  * AsyncSCSI returns unimpErr if the _SCSIAtomic (SCSI Manager 4.3)
  321.  * trap is not present. If so, just call the "old" OriginalSCSI.
  322.  */
  323. OSErr                        AsyncSCSI(
  324.         DeviceIdent                scsiDevice,            /* -> Bus/target/LUN        */
  325.         const SCSI_CommandPtr    scsiCommand,        /* The actual scsi command    */
  326.         unsigned short            cmdBlockLength,        /* -> Length of CDB            */
  327.         Boolean                    writeToDevice,        /* TRUE to write            */
  328.         Ptr                        bufferPtr,            /* -> user data buffer        */
  329.         unsigned long            transferSize,        /* How much to transfer        */
  330.         unsigned short            scsiHandshake[handshakeDataLength],
  331.         SCSI_Sense_Data            *senseDataPtr,        /* Request Sense results    */
  332.         unsigned long            senseDataSize,        /* Request Sense data size    */
  333.         unsigned long            completionTimeout,    /* Ticks to wait            */
  334.         unsigned short            *stsBytePtr,        /* <- status phase byte        */
  335.         unsigned long            *actualTransferCount
  336.     );
  337.  
  338. /*
  339.  * String formatting utilities (for debugging/display)
  340.  */
  341. /*
  342.  * AppendChar writes a character into the string. Note that
  343.  * it wraps around if the string size exceeds 255 bytes.
  344.  */
  345. #define AppendChar(result, c) (result[++result[0]] = (c))
  346. void                        AppendUnsigned(
  347.         StringPtr                result,
  348.         unsigned long            value
  349.     );
  350. void                        AppendSigned(
  351.         StringPtr                result,
  352.         signed long                value
  353.     );
  354. void                        AppendUnsignedLeadingZeros(
  355.         StringPtr                result,
  356.         unsigned long            value,
  357.         short                    fieldWidth,
  358.         short                    terminatorChar
  359.     );
  360. void                        AppendHexLeadingZeros(
  361.         StringPtr                result,
  362.         unsigned long            value,
  363.         short                    fieldWidth
  364.     );
  365. void                        AppendUnsignedInField(
  366.         StringPtr                result,
  367.         unsigned long            value,
  368.         short                    fieldWidth
  369.     );
  370. void                        AppendBytes(
  371.         StringPtr                result,
  372.         const Ptr                source,
  373.         unsigned short            length
  374.     );
  375. void                        AppendPascalString(
  376.         StringPtr                result,
  377.         const StringPtr            value
  378.     );
  379. void                        AppendCString(
  380.         StringPtr                result,
  381.         const char                *source,
  382.         unsigned short            maxLength        /* Ignored if zero    */
  383.     );
  384. void                        AppendOSType(
  385.         StringPtr                result,
  386.         OSType                    value
  387.     );
  388. /*
  389.  * Window Utilities
  390.  */
  391. void                        DoZoomWindow(
  392.         WindowPtr                theWindow,
  393.         short                    whichPart
  394.     );
  395. Boolean                        DoGrowWindow(
  396.         WindowPtr                theWindow,
  397.         Point                    eventWhere,
  398.         short                    minimumWidth,
  399.         short                    minimumHeight
  400.     );
  401. void                        MyDrawGrowIcon(
  402.         WindowPtr                theWindow
  403.     );
  404.  
  405. /*
  406.  * Format a block of data into the log.
  407.  */
  408. void                        DisplayDataBlock(
  409.         Ptr                        dataPtr,
  410.         unsigned short            dataLength
  411.     );
  412. /*
  413.  * Cheap 'n dirty pascal string copy routine.
  414.  */
  415. #define pstrcpy(dst, src) do {                            \
  416.         StringPtr    _src = (StringPtr) (src);            \
  417.         BlockMove(_src, dst, _src[0] + 1);                \
  418.     } while (0)
  419. /*
  420.  * Cheap 'n dirty pascal string concat.
  421.  */
  422. #define pstrcat(dst, src) do {                            \
  423.         StringPtr        _dst = (dst);                    \
  424.         StringPtr        _src = (StringPtr) (src);        \
  425.         short            _len;                            \
  426.         _len = 255 - _dst[0];                            \
  427.         if (_len > _src[0]) _len = _src[0];                \
  428.         BlockMove(&_src[1], &_dst[1] + _dst[0], _len);    \
  429.         _dst[0] += _len;                                \
  430.     } while (0)
  431.  
  432. /*
  433.  * Cheap 'n dirty memory clear routine.
  434.  */
  435. #define CLEAR(record) do {                                \
  436.         register char    *ptr = (char *) &record;        \
  437.         register long    size;                            \
  438.         for (size = sizeof record; size > 0; --size)    \
  439.             *ptr++ = 0;                                    \
  440.     } while (0)
  441.  
  442. #define width(r)    ((r).right - (r).left)
  443. #define height(r)    ((r).bottom - (r).top)
  444.  
  445. #define LOG(what)    DisplayLogString(gLogListHandle, (what))
  446. #define VERBOSE(what) do {                                \
  447.         if (gVerboseDisplay)                            \
  448.             LOG(what);                                    \
  449.     } while (0)
  450. /*
  451.  * Global variables.
  452.  */
  453. EXTERN WindowPtr                gMainWindow;
  454. EXTERN EventRecord                gCurrentEvent;
  455. #define EVENT                    (gCurrentEvent)
  456. EXTERN ListHandle                gLogListHandle;
  457. EXTERN THPrint                    gPrintHandle;
  458. EXTERN Boolean                    gQuitNow;
  459. EXTERN Boolean                    gUpdateMenusNeeded;
  460. EXTERN Boolean                    gInForeground;
  461. /*
  462.  * These flags are set/cleared by menu options to control the asynchronous SCSI
  463.  * Manager -- they are not used if the asynchronous manager is not present.
  464.  *    gEnableNewSCSIManager        FALSE to always use the original manager,
  465.  *                                even if the new manager is present.
  466.  *    gEnableSelectWithATN        FALSE to supress Select With ATN.
  467.  *    gDoDisconnect                Set the scsibDoDisconnect flag
  468.  *    gDontDisconnect                Set the scsibDontDisconnect flag.
  469.  *                                Note: both "do" and "don't" may be set.
  470.  */
  471. EXTERN Boolean                    gEnableNewSCSIManager;
  472. EXTERN Boolean                    gEnableSelectWithATN;
  473. EXTERN Boolean                    gDoDisconnect;
  474. EXTERN Boolean                    gDontDisconnect;
  475. EXTERN Boolean                    gVerboseDisplay;
  476. EXTERN MenuHandle                gAppleMenu;
  477. EXTERN MenuHandle                gFileMenu;
  478. EXTERN MenuHandle                gEditMenu;
  479. EXTERN MenuHandle                gTestMenu;
  480. EXTERN MenuHandle                gCurrentBusMenu;
  481. EXTERN MenuHandle                gCurrentTargetMenu;
  482. EXTERN MenuHandle                gCurrentLUNMenu;
  483. EXTERN DeviceIdent                gCurrentDevice;
  484. EXTERN unsigned short            gMaxLogicalUnit;
  485. EXTERN DeviceIdent                *gDeviceList;
  486. EXTERN unsigned short            gMaxDevice;        /* Number of items in gDeviceList    */
  487.  
  488. #endif        /* REZ            */
  489.